package main

import (
	"antifake/production"
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	sc "github.com/hyperledger/fabric/protos/peer"
)

type SmartContract struct {
}

var logger = shim.NewLogger("Tracker")

func (s *SmartContract) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
	return shim.Success(nil)
}

func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response {

	// Retrieve the requested Smart Contract function and arguments
	function, args := APIstub.GetFunctionAndParameters()
	// Route to the appropriate handler function to interact with the ledger appropriately
	if function == "queryCar" {
		return s.queryCar(APIstub, args)
	} else if function == "enterItems" {
		return s.enterItems(APIstub, args)
	} else if function == "queryQRInfo" {
		return s.queryQRInfo(APIstub, args)
	} else if function == "setHash" {
		return s.setHash(APIstub, args)
	} else if function == "checkHash" {
		return s.checkHash(APIstub, args)
	}

	return shim.Error("Invalid Smart Contract function name.")
}

func (s *SmartContract) queryCar(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	carAsBytes, _ := APIstub.GetState(args[0])
	return shim.Success(carAsBytes)
}

func (s *SmartContract) enterItems(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {

	if len(args) != 11 {
		return shim.Error("Incorrect number of arguments. Expecting 11")
	}

	itemsInfo := production.UnitInfo{
		args[1],
		args[2],
		args[3],
		args[4],
		args[5],
		args[6],
		args[7],
		args[8],
		args[9],
	}

	var itemNos []string
	err := json.Unmarshal([]byte(args[10]), &itemNos)
	if err != nil {
		return shim.Error("系统错误。")
	}

	BatchInfo := production.ProductUnit{
		itemsInfo,
		itemNos,
	}
	return BatchInfo.SaveProductUnitInfo(APIstub, args[0])
}

func (s *SmartContract) queryQRInfo(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
	if len(args) != 3 {
		return shim.Error("Incorrect number of arguments. Expecting 3")
	}

	value, err := APIstub.GetState(args[0])
	if err != nil {
		return shim.Error("系统错误。")
	} else if value == nil {
		return s.queryByQRFirstTime(APIstub, args)
	} else {
		return s.queryByQR(APIstub, args, value)
	}
}

func (s *SmartContract) queryByQRFirstTime(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {

	p := production.ProductUnit{}
	p.QueryProductUnitInfo(APIstub, args[0])
	qR := production.QRInfo{}
	qR.ItemInfo = p.BatchInfo
	value, err := json.Marshal(qR)
	if err != nil {
		return shim.Error("系统错误。")
	}

	err = p.Repackage(APIstub, args[1], args[2], args[0])
	if err != nil {
		return shim.Error(err.Error())
	}

	return shim.Success(value)
}

//func operationAfterFirstQuery(APIstub shim.ChaincodeStubInterface, args []string) error {
//
//	if len(args) != 4 {
//		return fmt.Errorf("Incorrect number of arguments. Expecting 4")
//	}
//
//	p := production.ProductUnit{}
//	err := p.QueryProductUnitInfo(APIstub, args[0], args[1])
//	if err != nil {
//		return err
//	}
//	err = p.Repackage(APIstub, args[2], args[3], args[1])
//	if err != nil {
//		return err
//	}

//	return nil
//}

func (s *SmartContract) queryByQR(APIstub shim.ChaincodeStubInterface, args []string, value []byte) sc.Response {

	//if len(args) != 3 {
	//	return shim.Error("Incorrect number of arguments. Expecting 3")
	//}

	qR := production.QRInfo{}
	err := qR.QueryByQR(APIstub, args[0], value)
	if err != nil {
		return shim.Error(err.Error())
	}

	result, err := json.Marshal(qR)
	if err != nil {
		return shim.Error("系统错误。")
	}

	r := production.RepackageInfo{}
	err = r.UpdateQueryInfo(APIstub, args[1], args[2], args[0])
	if err != nil {
		return shim.Error(err.Error())
	}

	return shim.Success(result)
}

//func operationAfterQuery(APIstub shim.ChaincodeStubInterface, args []string) error {
//
//	if len(args) != 3 {
//		return fmt.Errorf("Incorrect number of arguments. Expecting 3")
//	}
//
//	r := production.RepackageInfo{}
//	err := r.UpdateQueryInfo(APIstub, args[1], args[2], args[0])
//	if err != nil {
//		return err
//	}
//
//	return nil
//}

func (s *SmartContract) setHash(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	err := APIstub.PutState(args[0], []byte(args[1]))
	if err != nil {
		return shim.Error("系统错误。")
	}

	return shim.Success(nil)
}

func (s *SmartContract) checkHash(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	hash, err := APIstub.GetState(args[0])
	if err != nil {
		return shim.Error(err.Error())
	}
	if hash == nil {
		return shim.Error("此键值不可用。")
	} else if string(hash) != args[1] {
		return shim.Error("出现非法数据。")
	}

	return shim.Success(nil)
}

func main() {

	// Create a new Smart Contract
	err := shim.Start(new(SmartContract))
	if err != nil {
		fmt.Printf("Error creating new Smart Contract: %s", err)
	}
}
